﻿using AppData;
using Microsoft.International.Converters.PinYinConverter;
using MySqlX.XDevAPI.Relational;
using AppServer;
using System;
using System.Collections.Generic;
using System.Net.Http.Headers;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Net;

public enum SqlTable
{
    //用户表
    users,

    //设备
    device,

    //支付表
    payment,

    //申请
    //动态
    moments,

    //评论
    comments,

    //books
    movies_A,
    movies_B,
    movies_C,
    movies_D,
    movies_E,
    movies_F,
    movies_G,
    movies_H,
    movies_I,
    movies_J,
    movies_K,
    movies_L,
    movies_M,
    movies_N,
    movies_O,
    movies_P,
    movies_Q,
    movies_R,
    movies_S,
    movies_T,
    movies_U,
    movies_V,
    movies_W,
    movies_X,
    movies_Y,
    movies_Z,
}

public class SqlTableClass
{
    public long id;

    public SqlTableClass()
    {

    }
}

public class UserTable
{
    public int dbId;
    public users user;

    public UserTable(int dbId, users user)
    {
        this.dbId = dbId;
        this.user = user;
    }
}


public class device : SqlTableClass
{
    public int login_type;
    public string uuid;
    public string password;
    //public long uid;
    public string lang_type;
    public string os;
    public string device_model;
    public string device_name;

    public device() : base()
    {

    }
    public device( int login_type, string uuid, string lang_type, string os, string device_model, string device_name):base()
    {
        this.login_type = login_type;
        this.uuid = uuid;
        this.lang_type = lang_type;
        this.os = os;
        this.device_model = device_model;
        this.device_name = device_name;
    }

    public static int UpdateUUID(long deviceId, string username, string password)
    {
        return MysqlFunction.UpdateValues(ServerConfig.DBShared, SqlTable.device.ToString(),new string[] { "uuid" ,"password"},new string[] { username ,password}, new string[] { "id" }, new string[] { deviceId.ToString() });
    }

}



public class payment : SqlTableClass
{
    public long uid;
    public string goods_id;
    public string product_id;
    public int pay_type;
    public string transaction_id;
    public string receipt;

    public payment() : base()
    {

    }

    public payment(long uid,string goods_id, string product_id, int pay_type, string transaction_id, string receipt)
    {
        this.uid = uid;
        this.goods_id = goods_id;
        this.product_id = product_id;
        this.pay_type = pay_type;
        this.transaction_id = transaction_id;
        this.receipt = receipt;
    }

    public static bool TransactionExist(long deviceId,string transactionId)
    {
        string database = users.GetUserDatabaseWithDeviceId(deviceId);

        payment exist =  MysqlFunction.FindInTable<payment>(database, SqlTable.payment.ToString(), "transaction_id", transactionId);
        return exist != null;
    }

}


public class comments : SqlTableClass
{
    public long moment_user_id;
    public long moment_id;
    public long uid;
    public long time;
    public string content;
    public string likes;
    public string subcomments;

    public comments() : base()
    {

    }

    public comments(long moment_user_id,long moment_id, long uid, long time, string content, string likes, string subcomments)
    {
        this.moment_user_id = moment_user_id;
        this.moment_id = moment_id;
        this.uid = uid;
        this.time = time;
        this.content = content;
        this.likes = likes;
        this.subcomments = subcomments;
    }

    public static int SetSubcomments(long momentUserId,long commentId, string subcomments)
    {
        string database = users.GetUserDatabaseWithDeviceId(momentUserId);

        int row = MysqlFunction.UpdateValues(database, SqlTable.comments.ToString(),
            new string[] {  "subcomments" },
            new string[] {   subcomments },
            new string[] { "id" }, new string[] { commentId.ToString() });

        return row;
    }

    public static long AddComment(long momentUserId, long moment_id, long commentUserId, long time, string content, string likes)
    {
        string database = users.GetUserDatabaseWithDeviceId(momentUserId);

        GameDebug.Log($"插入新行 SetComment moment_id：{moment_id} time：{time} database:{database}");

        comments table = new comments(momentUserId,moment_id, commentUserId, time, content, likes, "");

        long id = MysqlFunction.InsertIntoTable(database, SqlTable.comments.ToString(), table);
        return id;
    }
    public static int UpdateLikes(long opponent, long commentId, long[] likes)
    {
        string database = users.GetUserDatabaseWithDeviceId(opponent);

        GameDebug.Log($" userId：{opponent} Comment {commentId} 更新likes：{likes.Length} database:{database}");

        int row = MysqlFunction.UpdateValue(database, SqlTable.comments.ToString(), "likes",
         users.LongList2String(likes.AsList()), "id", commentId.ToString());

        return row;
    }
}

public class moments : SqlTableClass
{
    public long uid;
    public long time;
    public string user_location_city;
    public string content;
    public string location;
    public string topic;
    public int moment_status;
    public string likes;
    public string comments;
   // public Tex[] texs;

    public moments() : base()
    {

    }
    public moments(long uid, string user_location_city, long time, string content, string location, string topic, int moment_status, string likes, string comments)
    {
        this.uid = uid;
        this.user_location_city = user_location_city;
        this.time = time;
        this.content = content;
        this.location = location;
        this.topic = topic;
        this.moment_status = moment_status;
        this.likes = likes;
        this.comments = comments;
    }

    public static long AddMoment(long userId, string user_location_city, long time, string content,string location, string topic,int momentStatus, string likes,string comments)
    {
        string database = users.GetUserDatabaseWithDeviceId(userId);

        GameDebug.Log($"插入新行 AddMoment userId：{userId} time：{time} database:{database}");

        moments table = new moments(userId, user_location_city, time, content, location, topic, momentStatus, likes, comments);

        long id = MysqlFunction.InsertIntoTable(database, SqlTable.moments.ToString(), table);
        return id;
    }

    public static int UpdateLikes(long opponent,long momentId, long[] likes)
    {
        string database = users.GetUserDatabaseWithDeviceId(opponent);

        GameDebug.Log($" userId：{opponent} Moment {momentId} 更新likes：{likes.Length} database:{database}");

        int row = MysqlFunction.UpdateValue(database, SqlTable.moments.ToString(), "likes",
         users.LongList2String(likes.AsList()), "id", momentId.ToString());

        return row;
    }
    public static int UpdateComments(long momentuserId, long momentId, List<long> commentIds)
    {
        string database = users.GetUserDatabaseWithDeviceId(momentuserId);

        GameDebug.Log($" userId：{momentuserId} Moment {momentId} 更新commentIds：{commentIds.Count} database:{database}");

        int row = MysqlFunction.UpdateValue(database, SqlTable.moments.ToString(), "comments",
         users.LongList2String(commentIds), "id", momentId.ToString());

        return row;
    }
}
public class videos : SqlTableClass
{
    public long movie_id;
    public int episode_id;
    public string name;
    public string description;
    public int approved;
    public int publish_date;
    public long watch_times;

    public videos() { }

    public videos(long movie_id, int episode_id, string title, string desc, int published_date, bool approved,long watch_times)
    {
        this.movie_id = movie_id;
        this.episode_id = episode_id;
        this.name = title;
        this.description = desc;
        this.publish_date = published_date;
        this.approved = approved ? 1 : 0;
        this.watch_times = watch_times;
    }

    public static videos AddVideo(long movie_id, int episode_id,
    string title,string desc, int published_date, bool approved)
    {
        string database = ServerConfig.DBVideos;

        var exist = TableHelper.FindInVideoTableWithEpisode(movie_id, episode_id);

        if (exist == null)
        {
            var tableName = GetVideoTable(movie_id);

            GameDebug.Log($"插入新行 Add video name：{title} database:{database} tableName:{tableName}");

            videos table = new videos(movie_id, episode_id, title, desc, published_date, approved,0);

            long id = MysqlFunction.InsertIntoTable(database, tableName, table);
            table.id = id;
            return table;
        }
        else
        {
            return exist;
        }
    }

    void UpdateWatchTimes(long movieId, long videoId, long watchTimes)
    {
        string database = ServerConfig.DBVideos;

        var exist = TableHelper.FindInVideoTable(movieId, videoId);

        if (exist != null)
        {
            MysqlFunction.UpdateValue(database, GetVideoTable(movieId),
                "watch_times", watchTimes.ToString(), "id", videoId.ToString());
        }
    }
    public static string GetVideoTable(long movieId)
    {
        var index = movieId % 100;
        return "videos_" + index;
    }
}

    public class movies : SqlTableClass
{
    public long id;
    public int episode_count;
    public string name;
    public string sub_genre;
    public string description;
    public string author;
    public string publisher;
    public int publish_date;
    public long watch_times;

    public movies() : base()
    {

    }
    public movies(int episodeCount,string name, string sub_genre, string description, string author, string publisher, int publishDate, long watchTimes)
    {
        this.episode_count = episodeCount;
        this.sub_genre = sub_genre;
        this.name = name;
        this.description = description;
        this.author = author;
        this.publisher = publisher;
        this.publish_date = publishDate;
        this.watch_times = watchTimes;
    }

    public static movies AddMovie(string title, int episodeCount,string sub_genre,  string description, string author, string publisher, int publishDate)
    {
        string database = ServerConfig.DBMovies;

        var exist = TableHelper.FindInMovieTable(title);

        if (exist == null)
        {
            var tableName = GetMovieTable(title);

            GameDebug.Log($"插入新行 AddBook genre：{sub_genre} name：{title} database:{database} tableName:{tableName}");

            movies table = new movies(episodeCount, title, sub_genre, description, author, publisher, publishDate,0);

            long id = MysqlFunction.InsertIntoTable(database, tableName, table);
            table.id = id;
            return table;
        }
        else
        {
            return exist;
        }
    }
    public static bool ContainsChinese(string str)
    {
        if (Regex.IsMatch(str, @"[\u4e00-\u9fa5]+"))
        {
            //Console.WriteLine("字符串中有汉字");
            return true;
        }
        else
        {
            //Console.WriteLine("字符串中无汉字");
            return false;
        }
    }
    public static string GetMovieGenre(string name)
    {
        if (string.IsNullOrEmpty(name))
        {
            return "";
        }
        var firstChar = name.Substring(0, 1);
        if (ContainsChinese(firstChar))
        {
            ChineseChar chineseChar = new ChineseChar(firstChar[0]);
            string firstZi = chineseChar.Pinyins[0];
            return firstZi.Substring(0, 1).ToUpper();
        }
        else
        {
            return firstChar.ToUpper();
        }
    }

    public static string GetMovieTable(string name)
    {
        string genre = GetMovieGenre(name);

        if (string.IsNullOrEmpty(genre))
        {
            return SqlTable.movies_A.ToString();
        }
        if (Enum.TryParse("movies_" + genre,out SqlTable table))
        {
            GameDebug.Log($"{name} parse to table:{table}");
            return table.ToString();
        }
        else
        {
            return SqlTable.movies_A.ToString();
        }
    }
    public static int UpdateLikes(SqlTable table, long bookId, long[] likes)
    {
        string database = ServerConfig.DBMovies;

        GameDebug.Log($"  {bookId} 更新likes：{likes.Length} database:{database}");

        int row = MysqlFunction.UpdateValue(database, table.ToString(), "likes",
         users.LongList2String(likes.AsList()), "id", bookId.ToString());

        return row;
    }
    public static int UpdateComments(long bookId, List<long> commentIds)
    {
        string database = ServerConfig.DBMovies;

        GameDebug.Log($" book {bookId} 更新commentIds：{commentIds.Count} database:{database}");

        int row = MysqlFunction.UpdateValue(database, SqlTable.comments.ToString(), "comments",
         users.LongList2String(commentIds), "id", bookId.ToString());

        return row;
    }

    public static int UpdateEpisodeCount(long movieId,string title, int episodeCount)
    {
        string database = ServerConfig.DBMovies;
        int row = MysqlFunction.UpdateValue(database,GetMovieTable(title), "episode_count",
        episodeCount.ToString(), "id", movieId.ToString());
        return row;
    }
}